#define _GNU_SOURCE
#include "daemon_sub_process.h"
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <sys/reboot.h>
#include <signal.h>
#include "log/log.h"

/**
 * 初始化子进程
 */
SubProcess *daemon_sub_process_init(char *cmd_param)
{
    SubProcess *sub_process = malloc(sizeof(SubProcess));
    sub_process->cmd_param = cmd_param;
    sub_process->pid = -1;
    sub_process->fail_count = 0;
    return sub_process;
}

/**
 * 查检并启动子进程
 */
int daemon_sub_process_checkStart(SubProcess *sub_process)
{
    int exit_status = 0;
    // 检查子进程的情况
    // 已启动过，且当前还活着
    if (sub_process->pid>0 && waitpid(sub_process->pid, &exit_status, WNOHANG) == 0)
    {
        return 0; // 子进程正在运行中，无需处理
    }
    // 已启动过，但当前已经挂了
    // 如果是异常挂掉，失败次数加1，达到阈值则重启
    if (exit_status!=0)
    {
        sub_process->fail_count++;
        if (sub_process->fail_count>MAX_FAIL_COUNT)
        {
            log_error("子进程异常退出次数太多，重启系统");
            reboot(RB_AUTOBOOT);
        }
}

    // 未启动过或未达到异常退出的阈值，则启动子进程
  sub_process->pid = fork();
  if(sub_process->pid == 0)
  {
    // 子进程
        char *argv[] = {EXE_NAME, sub_process->cmd_param, NULL}; 
        execve(EXE_NAME, argv, NULL);
        log_error("执行 %s 失败", sub_process->cmd_param);
        _exit(EXIT_FAILURE);
}

    return 0;
}

/**
 * 结束子进程
 */
void daemon_sub_process_exit(SubProcess *sub_process)
{
    // kill子进程，并发送SIGTERM信号
    kill(sub_process->pid, SIGTERM);
    // 等待子进程结束
    waitpid(sub_process->pid, NULL, 0);
    // 释放内存
    free(sub_process);
}
